package com.balloon.gateway.security.handler;

import com.balloon.gateway.comm.ResultVO;
import com.balloon.gateway.comm.ResultVOUtils;
import com.balloon.gateway.enums.StatusCodeEnums;
import com.balloon.gateway.exception.SmsCodeErrorException;
import com.balloon.gateway.exception.TokenParseErrorException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;


/**
 * @author liaofuxing
 * @version 1.0.0
 * @date 2022/3/8 12:32
 * @description 登录失败Handler
 */
@Component
public class DefaultAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {

    private static final Logger logger = LoggerFactory.getLogger(ServerAuthenticationFailureHandler.class);

    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
        return Mono.defer(() -> Mono.just(webFilterExchange.getExchange()
                                    .getResponse()).flatMap(response -> {
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            response.setStatusCode(HttpStatus.FORBIDDEN);
            ResultVO<Object> resultVO = null;
            if (exception instanceof UsernameNotFoundException) {
                // 用户名错误
                resultVO =   ResultVOUtils.username_not_found(StatusCodeEnums.USERNAME_NOT_FOUND.getName());
            } else if (exception instanceof BadCredentialsException) {
                // 密码错误
                resultVO = ResultVOUtils.login_failure(StatusCodeEnums.LOGIN_FAILURE.getName());
            } else if (exception instanceof AccountExpiredException) {
                // 账号已过期
                resultVO = ResultVOUtils.credentials_expired(StatusCodeEnums.CREDENTIALS_EXPIRED.getName());
            } else if (exception instanceof LockedException) {
                // 账号已被锁定
                resultVO = ResultVOUtils.account_locked(StatusCodeEnums.ACCOUNT_DISABLED.getName());
            } else if (exception instanceof CredentialsExpiredException) {
                // 用户凭证已失效
                resultVO = ResultVOUtils.credentials_expired(StatusCodeEnums.CREDENTIALS_EXPIRED.getName());
            } else if(exception instanceof TokenParseErrorException){
                // token解析错误
                resultVO = ResultVOUtils.token_parse_error(StatusCodeEnums.TOKEN_PARSE_ERROR.getName());
            } else if (exception instanceof DisabledException) {
                resultVO = ResultVOUtils.account_disabled(StatusCodeEnums.ACCOUNT_DISABLED.getName());
            } else if (exception instanceof SmsCodeErrorException) {
                resultVO = ResultVOUtils.sms_code_error(StatusCodeEnums.SMS_CODE_ERROR.getName());
            }
            exception.printStackTrace();
            logger.info(exception.getMessage());
            ObjectMapper objectMapper = new ObjectMapper();
            String json = "";
            try {
                json = objectMapper.writeValueAsString(resultVO);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            DataBuffer dataBuffer = dataBufferFactory.wrap(json.getBytes());
            return response.writeWith(Mono.just(dataBuffer));

        }));
    }
}